﻿//
// Created by gogoqiu on 2021/8/20.
//

#ifndef UNTITLED2_PREFERENCE_H
#define UNTITLED2_PREFERENCE_H
#include <wx/wx.h>
#include <utility>
#include <vector>
#include <sqlite3.h>
//#include "MyTagApp.h"

using namespace std;

enum PreferenceType{
    PT_INPUT = 0, PT_SWITCH, PT_LIST
};

class PreferenceView;

/**
 * 核心数据
 * key
 * title
 * value
 */
class PreferenceItem{
    friend class PreferenceView;
protected:
    wxString key;
    wxString value;
    wxString defaultValue;

    bool valueIsNull;

    PreferenceItem(){
        valueIsNull = false;
    };
public:
    static PreferenceItem* NullValueItem( const wxString& key,
                                          const wxString& defaultValue){
        auto* item = new PreferenceItem;
        item->key = key;
        //item->value = 0;
        return item;
    }

    PreferenceItem( const wxString& key,
        const wxString& value,
        const wxString& defaultValue){
        this->key = key;
        this->value = value;
        this->defaultValue = defaultValue;
        valueIsNull = false;
    }

    PreferenceItem( const wxString& key,
                    const wxString& value,
                    const wxString& defaultValue,
                    bool _valueIsNull ){
        this->key = key;
        this->value = value;
        this->defaultValue = defaultValue;
        valueIsNull = _valueIsNull;
    }

    //
    wxString getSql( wxString tag ){
        wxString sql;
        wxString _value = value;
        //把26个字母打一遍，然后通过php的addslashes查看哪些字符变化了
        _value.Replace("\\", "\\\\");
        _value.Replace("\"", "\\\"");
        _value.Replace("\'", "\\\'");
        //sql.sprintf(base, filename, filesize, file_hash);
        sql.sprintf("insert into preferences( tag, key, defaultValue, value ) values( '%s', '%s', '%s', '%s' )",
                    tag, key, this->defaultValue, _value );
        //wxString _sql = sql.mb_str(wxConvUTF8);
        return sql;
    }

    wxString getKey(){
        return key;
    }

    wxString getValue(){
        return value;
    }

    wxString getDefaultValue(){
        return defaultValue;
    }

    void setValueIsNull( bool _valueIsNull ){
        this->valueIsNull = _valueIsNull;
    }

    void setValue( wxString v ){
        value = v;
    }

    bool getValueIsNull(  ) const{
        return this->valueIsNull;
    }
};
/**
 * PreferenceView,
 * 存储模式
 * 往下滚动，延长
 */
class PreferenceView :public PreferenceItem{
protected:
    PreferenceType type;
    wxString title;
    int id;
    wxWindowBase * control;
public:
    PreferenceView(const wxString &key, const wxString &value,
                   const wxString &defaultValue, PreferenceType type, const wxString& title )
            : PreferenceItem(key, value, defaultValue) {
        this->type = type;
        this->title = title;
    }

    PreferenceView( PreferenceItem item, PreferenceType type, const wxString& title )
            : PreferenceItem( std::move(item) ) {
        this->type = type;
        this->title = title;
    }

    PreferenceView( PreferenceItem *item, PreferenceType type, const wxString& title ):
        PreferenceItem( item->key, item->value, item->defaultValue ) {
        //this->value = item->key;
        this->type = type;
        this->title = title;
    }

    PreferenceType getType(){
        return type;
    }

    wxString getTitle(){
        return title;
    }

    /*
    int getId(){
        return id;
    }

    wxTextCtrl *textCtrl;
    wxTextCtrl *valueCtrl;
    //
    wxBoxSizer* buildView( wxWindow *parent ){

        wxBoxSizer* listItemSizer = new wxBoxSizer(wxVERTICAL);
        //Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&wxtestDialog::OnAbout);
        textCtrl = new wxTextCtrl( parent,  id, this->title, wxDefaultPosition, wxDefaultSize,
                                   0, wxDefaultValidator, _T("ID_TEXTCTRL1"));
        valueCtrl = new wxTextCtrl( parent,  id, this->title, wxDefaultPosition, wxDefaultSize,
                                    0, wxDefaultValidator, _T("ID_TEXTCTRL1"));
        listItemSizer->Add( textCtrl );
        listItemSizer->Add( valueCtrl );
        return listItemSizer;
    }*/
    //virtual wxBoxSizer* buildView( wxWindow *parent ) = 0;
    void setControl(wxWindowBase * _control){
        this->control = _control;
    }

    wxWindowBase * getControl(){
        return control;
    }
};

struct OnPreferenceStorageSession{
    void OnRunSqlOk();
    void OnRunSqlError(wxString errMsg);
};

/**
 *
 */
class PreferenceStorage {
protected:
  vector<PreferenceItem*> preferences;
  //default
  //vector<PreferenceItem*> _preferences;
  //root view, list view

public:
  ~PreferenceStorage(){
      vector<PreferenceItem*>::iterator _iterator;
      for(_iterator = preferences.begin();_iterator!=preferences.end(); _iterator++ ){
          //preferences.swap()
          delete _iterator.operator*();
          _iterator.operator*() = 0;
      }
      //vector<Preference> tmp;
      //preferences.swap( tmp );
  }

  void add( PreferenceItem *preference ){
      preferences.push_back( preference );
  }

  //void BuildView();

  virtual int Save() = 0;

  virtual int Load() = 0;

  virtual int InitTable() = 0;

  virtual int updateItem( const wxString& key, const wxString&  ) = 0;

  vector<PreferenceItem*> getPreferences() {
    return preferences;
  }

  virtual int RunSql( wxString sql ) = 0;
};

//
class MysqlPreferenceStorage: public PreferenceStorage{
public:
    //init
    MysqlPreferenceStorage();
    ~MysqlPreferenceStorage();
    //virtual int Save();
    int Save() override;
};

class MyTagApp;

class SqlitePreferenceStorage: public PreferenceStorage{
    //
    sqlite3* m_pDb;
    wxString tag;

    //static SqlitePreferenceStorage* instance;
protected:

    MyTagApp * myTagApp;
public:
    //
    //static SqlitePreferenceStorage* getDefaultSharedPreferences( const wxString& TAG );
    //
    int RunSql( wxString sql )override;

    explicit SqlitePreferenceStorage( MyTagApp * myTagApp );

    ~SqlitePreferenceStorage();

    int Save() override;
    int Save( vector<PreferenceItem*> items );

    int Load() override;

    int InitTable() override;

    int updateItem( const wxString& key, const wxString&  ) override;
};

/*
 * PreferenceStorage
 */
/*
class PreferenceScreen{
public:
    virtual void BuildView( wxDialog *) =0;
};*/

#ifdef __Win32__
class RegisterPreferenceStorage: public PreferenceStorage{

};
#endif
#endif //UNTITLED2_PREFERENCE_H
